package com.ly.gof.create.factory;

/**
 * @author liuyang
 * @des 抽象工厂模式
 * 通常适用于以下场景：
 * 当需要创建的对象是一系列相互关联或相互依赖的产品族时，如电器工厂中的电视机、洗衣机、空调等。
 * 系统中有多个产品族，但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
 * 系统中提供了产品的类库，且所有产品的接口相同，客户端不依赖产品实例的创建细节和内部结构。
 * 模式的扩展
 * 抽象工厂模式的扩展有一定的“开闭原则”倾斜性：
 * 当增加一个新的产品族时只需增加一个新的具体工厂，不需要修改原代码，满足开闭原则。
 * 当产品族中需要增加一个新种类的产品时，则所有的工厂类都需要进行修改，不满足开闭原则。
 * @Version 1.0
 * @Date: 21/07/2021 10:21
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product1 a;
            Product2 b;
            AbstractFactoryB af;
            String cName = ConcreteFactoryA1.class.getName();
            //System.out.println("新类名："+cName);
            //通过类名生成实例对象并将其返回
            Class<?> c = Class.forName(cName);
            Object obj = c.newInstance();
            af = (AbstractFactoryB)obj;
            a = af.newProduct1();
            a.show();
            b = af.newProduct2();
            b.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

//抽象产品：提供了产品的接口
interface Product1 {
    public void show();
}

interface Product2 {
    public void show();
}

//具体产品1：实现抽象产品中的抽象方法
class ConcreteProduct11 implements Product1 {
    public void show() {
        System.out.println("工厂1-->具体产品1显示...");
    }
}

//具体产品2：实现抽象产品中的抽象方法
class ConcreteProduct12 implements Product1 {
    public void show() {
        System.out.println("工厂2-->具体产品1显示...");
    }
}

//具体产品2：实现抽象产品中的抽象方法
class ConcreteProduct21 implements Product2 {
    public void show() {
        System.out.println("工厂1-->具体产品2显示...");
    }
}

//具体产品2：实现抽象产品中的抽象方法
class ConcreteProduct22 implements Product2 {
    public void show() {
        System.out.println("工厂2-->具体产品2显示...");
    }
}

//抽象工厂（Abstract Factory）：提供了创建产品的接口，它包含多个创建产品的方法 newProduct()，可以创建多个不同等级的产品。 抽象工厂：提供了厂品的生成方法
interface AbstractFactoryB {
    public Product1 newProduct1();

    public Product2 newProduct2();
}

//具体工厂1：实现了厂品的生成方法
class ConcreteFactoryB1 implements AbstractFactoryB {
    public Product1 newProduct1() {
        System.out.println("具体工厂 1 生成-->具体产品 11...");
        return new ConcreteProduct11();
    }

    public Product2 newProduct2() {
        System.out.println("具体工厂 1 生成-->具体产品 21...");
        return new ConcreteProduct21();
    }

}

//具体工厂2：实现了厂品的生成方法
class ConcreteFactoryB2 implements AbstractFactoryB {
    public Product1 newProduct1() {
        System.out.println("具体工厂 2 生成-->具体产品 11...");
        return new ConcreteProduct11();
    }

    public Product2 newProduct2() {
        System.out.println("具体工厂 2 生成-->具体产品 21...");
        return new ConcreteProduct21();
    }
}

